
interface IElmenetLocationSize {
    top: number;
    left: number;
    width: number;
    height: number;
}
let ActiveStructElement: StructElement | null = null;
const ActiveElementBorderColor = "#3961FF";
import { registryReSizeEvent, registryContainerEvent } from "./events";
import PlayGroundCanvas, { currentGridInfo } from "../playground/backgroundCanvas";
import EventMgr from "@/core/EventMgr";
import { getTop, getLeft } from "@/core/locationService";


export const ElementLocationSizeMap = new Map<HTMLElement, IElmenetLocationSize>();
export let currentPlayGround: PlayGroundCanvas;
export default class StructElement {
    private currentElement: HTMLElement;
    private borderElement: HTMLElement;
    private rightSizePointElement: HTMLElement;
    private bottomSizePointElement: HTMLElement;
    private rbSizePointElement: HTMLElement;
    private container: HTMLElement;
    private _show: boolean = true;
    private playGround: PlayGroundCanvas;
    reSizing: "toRight" | "toBottom" | "both" | null = null;
    reSizeMethod: "toRight" | "toBottom" | "both" | null = null;
    constructor(container: HTMLElement, playGround: PlayGroundCanvas, initTop: number = 2,
        initLeft: number = 2,
        initWidth: number = 3,
        initHeight: number = 2) {
        this.playGround = playGround;
        currentPlayGround = playGround;
        this.currentElement = document.createElement("div");
        this.borderElement = document.createElement("div");
        this.rightSizePointElement = document.createElement("div");
        this.bottomSizePointElement = document.createElement("div");
        this.rbSizePointElement = document.createElement("div");

        this.container = container;
        this.initStructElement(initTop, initLeft, initWidth, initHeight);
        this.initBorderElement();
        this.reSizeElement();

    }
    get show() {
        return this._show;
    }
    setShow(_show: boolean) {
        this._show = _show;
    }
    getCurrentElement() {
        return this.currentElement;
    }
    getBorderElement() { return this.currentElement; }
    getRightSizePointElement() { return this.rightSizePointElement; }
    getBottomSizePointElement() { return this.bottomSizePointElement; }
    getRbSizePointElement() { return this.rbSizePointElement; }
    getContainer() { return this.container; }

    private initBorderElement() {
        this.borderElement.setAttribute("style", `
            position:absolute;
            left:-10px;
            right:-10px;
            top:-10px;
            bottom:-10px;
            z-index:-1;
            border:2px dashed  ${ActiveElementBorderColor};
            display:none;
        `);
        const reSizePointStyle = `
            position:absolute;
            width:8px;
            height:8px;
            border-radius:2px;
            background:#fff;
            border:1px solid ${ActiveElementBorderColor};
        `;
        this.rightSizePointElement.setAttribute("style", reSizePointStyle + `
            top:50%;
            right:-6px;
            margin-top:-4px;
        `);
        this.rbSizePointElement.setAttribute("style", reSizePointStyle + `
            top:100%;
            right:-4px;
            margin-top:-4px;
        `);
        this.bottomSizePointElement.setAttribute("style", reSizePointStyle + `
        top:100%;
        left:50%;
        margin-top:-4px;
        margin-left:-4px;
    `);
        this.borderElement.appendChild(this.rightSizePointElement);
        this.borderElement.appendChild(this.bottomSizePointElement);
        this.borderElement.appendChild(this.rbSizePointElement);
        this.currentElement.appendChild(this.borderElement);
        registryReSizeEvent.bind(this)(this.borderElement);
    }
    private initStructElement(initTop: number = 2,
        initLeft: number = 2,
        initWidth: number = 3,
        initHeight: number = 2) {
        let gridWidth = currentGridInfo.gridWidth;
        let gridHeight = currentGridInfo.gridHeight;
        this.currentElement.style.cursor = "pointer";
        this.currentElement.setAttribute("style",
            `position: absolute;z-index:1;background:#fff;
            width:${gridWidth * initWidth + ((initWidth - 1) * currentGridInfo.waterTank)}px;
            height:${gridHeight * initHeight + ((initHeight - 1) * currentGridInfo.waterTank)}px;
            top:${getTop(initTop, currentGridInfo.gridHeight, currentGridInfo.waterTank)}px;
            left:${getLeft(initLeft, currentGridInfo.gridWidth, currentGridInfo.waterTank)}px;`);
        ElementLocationSizeMap.set(this.currentElement, {
            top: initTop,
            left: initLeft,
            width: initWidth,
            height: initHeight
        })
        this.container.appendChild(this.currentElement);
    }
    private reSizeElement() {
        const self = this;
        self.reSizing = self.reSizeMethod;
        registryContainerEvent.bind(this)(this.container);
    }
    active() {
        ActiveStructElement && ActiveStructElement.unActive();
        ActiveStructElement = this;
        this.borderElement.style.display = "block"
        this.currentElement.style.boxShadow = `0 0 10px 4px rgba(0,0,0,.1)`;
    }
    unActive() {
        this.borderElement.style.display = "none"
        // this.currentElement.style.boxShadow = ``;
    }
    getElement() {
        return this.currentElement;
    }
    setLocation(top: number, left: number) {
        const currentLocation = ElementLocationSizeMap.get(this.currentElement);
        if (!currentLocation)
            return;
        this.currentElement.style.left = (left + 1) * currentGridInfo.waterTank + currentLocation.left * currentGridInfo.gridWidth + "px";
        this.currentElement.style.top = (top + 1) * currentGridInfo.waterTank + currentLocation.top * currentGridInfo.gridHeight + "px";
    }
    getLocation() {
        return {
            left: 0,
            right: 0
        }
    }
}
let debounceTimer: number = 0 //借助闭包
function debounce(fn: Function, delay: number) {
    return function () {
        if (debounceTimer) {
            clearTimeout(debounceTimer) //进入该分支语句，说明当前正在一个计时过程中，并且又触发了相同事件。所以要取消当前的计时，重新开始计时
            debounceTimer = setTimeout(fn, delay)
        }
        debounceTimer = setTimeout(fn, delay)
    }
}